package com.geezdata.cps.base.shiro;

import java.io.Serializable;
import java.util.concurrent.TimeUnit;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;

import com.geezdata.cps.base.cache.redis.RedisKey;
import com.geezdata.cps.base.constant.ShiroConstants;

public class ShiroSession extends EnterpriseCacheSessionDAO {
    private static Logger logger = LoggerFactory.getLogger(ShiroSession.class);
    private RedisTemplate<Object, Object> redisTemplate;
    
    public ShiroSession(RedisTemplate<Object, Object> redisTemplate) {
    	this.redisTemplate = redisTemplate;
    }
    
    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = super.doCreate(session);
        logger.debug("RedisSession::doCreate {}", sessionId);
        final String redisKey = RedisKey.SHIRO_SESSION_PREFIX + sessionId.toString();
        redisTemplate.opsForValue().set(redisKey, session);
        redisTemplate.expire(redisKey, ShiroConstants.EXPIRE_TIME, TimeUnit.SECONDS);
        return sessionId;
    }

    @Override
    protected Session doReadSession(Serializable sessionId) {
        logger.debug("RedisSession::doReadSession {}", sessionId);
        Session session = super.doReadSession(sessionId);
        if (session == null) {
        	final String redisKey = RedisKey.SHIRO_SESSION_PREFIX + sessionId.toString();
        	session = (Session) redisTemplate.opsForValue().get(redisKey);
        }
        
        return session;
    }

    @Override
    protected void doUpdate(Session session) {
    	logger.debug("RedisSession::doUpdate {}", session.getId());
        super.doUpdate(session);
        final String redisKey = RedisKey.SHIRO_SESSION_PREFIX + session.getId().toString();
        if (!redisTemplate.hasKey(redisKey)) {
            redisTemplate.opsForValue().set(redisKey, session);
        }
        
        redisTemplate.expire(redisKey, ShiroConstants.EXPIRE_TIME, TimeUnit.SECONDS);
    }

    @Override
    protected void doDelete(Session session) {
        logger.debug("RedisSession::doDelete {}", session.getId());
        super.doDelete(session);
        final String redisKey = RedisKey.SHIRO_SESSION_PREFIX + session.getId().toString();
        redisTemplate.delete(redisKey);
    }
}